package cn.edu.gznu.wecampus.core.weixin.api;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

import cn.edu.gznu.wecampus.core.weixin.service.message.MessageException;
import cn.edu.gznu.wecampus.core.weixin.service.message.MessageProcessor;
import cn.edu.gznu.wecampus.core.weixin.service.message.Request;
import cn.edu.gznu.wecampus.core.weixin.service.message.Response;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/api/weixin")
@Slf4j
public class PushApi {
	
	@Value("${weixin.message.token}")
	private String token;
	
	@Value("${weixin.message.encodingAESKey}")
	private String encodingAESKey;
	
	@Value("${weixin.corpid}")
	private String corpid;
	
	@Autowired
	private MessageProcessor messageProcessor;

	@GetMapping("push")
	public String verfifyUrl(
		@RequestParam("msg_signature") String msgSignature,
		@RequestParam("timestamp") String timestamp,
		@RequestParam("nonce") String nonce,
		@RequestParam("echostr") String echostr) throws AesException {

		WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpid);
		
		String verifyurl = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
		System.out.println("verifyurl: " + verifyurl);
		return verifyurl;
	}
	
	@PostMapping(value = "push",
		consumes = "text/xml",
		produces = "text/xml"
	)
	public String push(
		@RequestParam("msg_signature") String msgSignature,
		@RequestParam("timestamp") String timestamp,
		@RequestParam("nonce") String nonce,
		@RequestBody String encryptRequest) throws Exception {
		XmlMapper xmlMapper = new XmlMapper();
		WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpid);
		String decryptRequest = wxcpt.DecryptMsg(msgSignature, timestamp, nonce, encryptRequest);
		log.info(decryptRequest);
        xmlMapper.setDefaultUseWrapper(false);
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Request request = xmlMapper.readValue(decryptRequest, Request.class);
        Response response = null;
		try {
	        response = messageProcessor.process(request);
	        if(response == null) {
	        	return "";
	        }
		} catch(MessageException e) {
	        response = new Response();
	        response.setFromUserName(request.getToUserName());
	        response.setToUserName(request.getFromUserName());
	        response.setCreateTime(request.getCreateTime());
	        response.setMsgType("text");
	        response.setContent(e.getMessage());
		}
        String decryptResponse = xmlMapper.writeValueAsString(response);
        String encryptResponse = wxcpt.EncryptMsg(decryptResponse, timestamp, nonce);
        return encryptResponse;
	}
}
